(define (compose f g)
  (lambda (x) (f (g x))))

(define (repeat f n) 
  (if (< n 1) 
    (lambda (x) x) 
    (compose f (repeat f (- n 1))))) 

(define (average-damp f)
  (lambda (x)
    (/ (+ x (f x)) 2)))

(define tolerance 0.00001)

(define (fixed-point f first-guess)
  (define (close-enough? v1 v2)
    (< (abs (- v1 v2)) tolerance))
  (define (try guess)
    (let ((next (f guess)))
     (if (close-enough? guess next)
       next
       (try next))))
  (try first-guess))

(define (fast-expt b n)
  (define (expt2 x) (* x x))
  (define (fast-expt-iter a count n-iter legency)
    (cond ((or (= 1 n-iter) (= count n-iter)) (* a legency))
          ((<= (* 2 count) n-iter) (fast-expt-iter (expt2 a) (* 2 count) n-iter legency))
          (else (fast-expt-iter b 1 (- n-iter count) (* a legency))))) 
  (cond ((= 0 n) 1) 
        ((= 1 n) b)
        (else (fast-expt-iter b 1 n 1))))

(define (log2 x) (/ (log x) (log 2))) 

(define (nth-root n x) 
 (fixed-point ((repeat average-damp (floor (log2 n)))  
               (lambda (y) (/ x (fast-expt y (- n 1))))) 
              1.0)) 


